﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using BlogPlat.Model;
using System.Text.RegularExpressions;
using BlogPlat.Model.Abstract;
using System.Data.Linq;

namespace BlogPlat.Model.Repositories
{
    public class PostRepository : IPostRepository
    {
        private Table<Post> _posts;

        public PostRepository(string connString)
        {
            _posts = (new DataContext(connString)).GetTable<Post>();
        }

        #region Interface IPostRepository Implementation
        public ICollection<Post> ListBlogEntriesArchive(int? year, int? month, int? day)
        {
            var query = Query();
            if (year.HasValue)
                query = query.Where(e => e.DatePublished.Year == year.Value);
            if (month.HasValue)
                query = query.Where(e => e.DatePublished.Month == month.Value);
            if (day.HasValue)
                query = query.Where(e => e.DatePublished.Day == day.Value);
            return (from p in query
                    select p)
                    .ToList();            
        }

        public ICollection<Post> ListNewestPublishedPosts()
        {
            return (from p in Query()
                    where p.IsDraft == false
                    select p)
                   .OrderByDescending(d => d.DatePublished)
                   .ToList();            
        }      

        public void Delete(int id)
        {
            Post entityToDelete = _posts.Where(p => p.ID == id).SingleOrDefault();
            if(entityToDelete != null)
                _posts.DeleteOnSubmit(entityToDelete);
        }

        public Post Get(int id)
        {
            return _posts.Where(p => p.ID == id).SingleOrDefault();
        }        

        public IQueryable<Post> Query()
        {
            return _posts;
        }

        /// <summary>
        /// Lists all (draft and published) blog posts
        /// </summary>
        /// <returns>List of blog posts</returns>
        public List<Post> ListEntries()
        {
            return _posts.ToList();
        }
      
        /// <summary>
        /// Submit changes to database.
        /// </summary>
        public void Save()
        {
            _posts.Context.SubmitChanges();            
        }        

        /// <summary>
        /// Increment view count by 1 each time a blog post is viewed regardless of ip address or anything (for now).
        /// Save method has to be called to ensure changes are submitted back to database.
        /// </summary>
        /// <param name="postID">Post ID which view count will be updated.</param>
        public void IncrementViewCount(int postID)
        {
            Post postToUpdate = _posts.Where(p => p.ID == postID).SingleOrDefault();

            postToUpdate.ViewCount++;
        }      

        public void Add(Post newEntity)
        {
            _posts.InsertOnSubmit(newEntity);
        }

        public ICollection<Post> List()
        {
            return _posts.ToList();
        }

        public void Update(Post entityToUpdate)
        {
            if (entityToUpdate.ID == 0)
                _posts.InsertOnSubmit(entityToUpdate);
            else if (_posts.GetOriginalEntityState(entityToUpdate) == null)
            {
                _posts.Attach(entityToUpdate);
                _posts.Context.Refresh(RefreshMode.KeepCurrentValues, entityToUpdate);
            }
        }

        public Post GetByFriendlyUrl(string friendlyUrl)
        {
            if (!string.IsNullOrEmpty(friendlyUrl))
                return _posts.Where(p => p.FriendlyUrl == friendlyUrl).SingleOrDefault();
            else return null;
        }
        #endregion        
    }
}
